home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1988 Hans-J. Boehm, Alan J. Demers */
- /**
- GRAB Graph Layout and Browser System
-
- Copyright (c) 1989, Tera Computer Company
- **/
-
- /*********************************/
- /* */
- /* Definitions for conservative */
- /* collector */
- /* */
- /*********************************/
-
- /*********************************/
- /* */
- /* Easily changeable parameters */
- /* */
- /*********************************/
-
- #define VAX /* This is a VAX, as opposed to a SPARC, */
- /* Motorola 68000 or I386. */
- /* We assume: M68K ==> Sun3, I386 ==> Sequent Symmetry */
- #define PRINTSTATS /* Print garbage collection statistics */
- /* For less verbose output, undefine in reclaim.c */
-
- #define PRINTTIMES /* Print the amount of time consumed by each garbage */
- /* collection. */
-
- #ifdef NOSTATS
- #undef PRINTSTATS
- #undef PRINTTIMES
- #endif
-
- #define PRINTBLOCKS /* Print object sizes associated with heap blocks, */
- /* whether the objects are atomic or composite, and */
- /* whether or not the block was found to be empty */
- /* duing the reclaim phase. Typically generates */
- /* about one screenful per garbage collection. */
- #undef PRINTBLOCKS
-
- #ifdef M68K
- # define UNALIGNED /* Pointers are not longword aligned */
- # define ALIGNMENT 2 /* Pointers are aligned on 2 byte boundaries */
- /* by the Sun C compiler. */
- #else
- # ifdef VAX
- # undef UNALIGNED /* Pointers are longword aligned by 4.2 C compiler */
- # define ALIGNMENT 4
- # else
- # ifdef SPARC
- # undef UNALIGNED
- # define ALIGNMENT 4
- # else
- # ifdef I386
- # undef UNALIGNED /* Sequent compiler aligns pointers */
- # define ALIGNMENT 4
- # else
- --> specify alignment <--
- # endif
- # endif
- # endif
- # endif
-
- # ifdef M68K
- # define STACKTOP ((char *)0xf000000) /* Beginning of stack on a Sun 3 */
- /* Sun 2 value is 0x1000000 */
- # else
- # ifdef VAX
- # define STACKTOP ((char *)0x80000000) /* Beginning of stack under 4.n BSD */
- # else
- # ifdef SPARC
- # define STACKTOP ((char *) 0xf8000000)
- # else
- # ifdef I386
- # define STACKTOP ((char *) 0x3ffff000) /* For Sequent */
- # else
- --> specify
- # endif
- # endif
- # endif
- # endif
-
- /* Start of data segment for each of the above systems. Note that the */
- /* default case works only for contiguous text and data, such as on a */
- /* Vax. */
- # ifdef M68K
- # define DATASTART ((char *)((((long) (&etext)) + 0x1ffff) & ~0x1ffff))
- # else
- # ifdef I386
- # define DATASTART ((char *)((((long) (&etext)) + 0xfff) & ~0xfff))
- # else
- # define DATASTART (&etext)
- # endif
- # endif
-
- # define HINCR 16 /* Initial heap increment, in blocks of 4K */
- # define HINCR_MULT 3 /* After each new allocation, hincr is multiplied */
- # define HINCR_DIV 2 /* by HINCR_MULT/HINCR_DIV */
- # define GC_MULT 3 /* Don't collect if the fraction of */
- /* non-collectable memory in the heap */
- /* exceeds GC_MUL/GC_DIV */
- # define GC_DIV 4
-
- # define NON_GC_HINCR 8 /* Heap increment if most of heap if collection */
- /* was suppressed because most of heap is not */
- /* collectable */
-
- /* heap address bounds. These are extreme bounds used for sanity checks. */
- /* HEAPLIM may have to be increased for machines with incredibly large */
- /* amounts of memory. */
-
- # ifdef M68K
- # define HEAPSTART 0x00010000
- # define HEAPLIM 0x04000000
- # else
- # ifdef SPARC
- # define HEAPSTART 0x00010000
- # define HEAPLIM 0x10000000
- # else
- # ifdef VAX
- # define HEAPSTART 0x400
- # define HEAPLIM 0x10000000
- # else
- # ifdef I386
- # define HEAPSTART 0x1000
- # define HEAPLIM 0x10000000
- # else
- --> values unknown <--
- # endif
- # endif
- # endif
- # endif
-
- /*********************************/
- /* */
- /* Machine-dependent defines */
- /* */
- /*********************************/
-
- #define WORDS_TO_BYTES(x) (((int)(x))<<2)
- #define BYTES_TO_WORDS(x) (((int)(x))>>2)
-
- #define WORDSZ 32
- #define LOGWL 5 /* log[2] of above */
- #define BYTES_PER_WORD (sizeof (word))
- #define NREGS 16
- #define ONES 0xffffffff
- #define MSBYTE 0xff000000
- #define SIGNB 0x80000000
- #define MAXSHORT 0x7fff
- #define modHALFWORDSZ(n) ((n) & 0xf) /* mod n by size of half word */
- #define divHALFWORDSZ(n) ((n) >> 4) /* divide n by size of half word */
- #define modWORDSZ(n) ((n) & 0x1f) /* mod n by size of word */
- #define divWORDSZ(n) ((n) >> 5) /* divide n by size of word */
- #define twice(n) ((n) << 1) /* double n */
-
- typedef unsigned long word;
-
- #define TRUE 1
- #define FALSE 0
-
- /*********************/
- /* */
- /* Size Parameters */
- /* */
- /*********************/
-
- /* heap block size, bytes */
- /* for RT see comment below */
-
- #define HBLKSIZE 0x1000
-
-
- /* max size objects supported by freelist (larger objects may be */
- /* allocated, but less efficiently) */
- /* asm(".set MAXOBJSZ,0x200") if HBLKSIZE/2 == 0x200 */
-
- #define MAXOBJSZ BYTES_TO_WORDS(HBLKSIZE/2)
- #define MAXAOBJSZ BYTES_TO_WORDS(HBLKSIZE/2)
-
- # define divHBLKSZ(n) ((n) >> 12)
-
- # define modHBLKSZ(n) ((n) & 0xfff)
-
- # define HBLKPTR(objptr) ((struct hblk *)(((long) (objptr)) & ~0xfff))
-
- # define MAXHBLKS 4000 /* Maximum number of chunks which can be */
- /* allocated */
-
-
- /********************************************/
- /* */
- /* H e a p B l o c k s */
- /* */
- /********************************************/
-
- /* heap block header */
- #define HBLKMASK (HBLKSIZE-1)
-
- #define BITS_PER_HBLK (HBLKSIZE * 8)
-
- #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/WORDSZ)
- /* upper bound */
- /* We allocate 1 bit/word. Only the first word */
- /* in each object is actually marked. */
-
- # define MARK_BITS_SZ ((MARK_BITS_PER_HBLK + WORDSZ - 1)/WORDSZ)
- /* Upper bound on number of mark words per heap block */
-
- struct hblkhdr {
- int hbh_sz; /* sz > 0 ==> objects are sz-tuples of poss. pointers */
- /* sz < 0 ==> objects are sz-tuples not pointers */
- /* if free, the size in bytes of the whole block */
- /* Misc.c knows that hbh_sz comes first. */
- struct hblk ** hbh_index; /* Pointer to heap block list entry */
- /* for this block */
- struct hblk * hbh_next; /* Link field for hblk free list */
- long hbh_mask; /* If hbh_mask >= 0 then: */
- /* x % (4 * hbh_sz) == x & hbh_mask */
- /* sz is a power of 2 and < the size of a heap */
- /* block. */
- /* A hack to speed up pointer validity check on */
- /* machines with slow division. */
- long hbh_marks[MARK_BITS_SZ];
- /* Bits 2i and 2i+1 in the array refer to the */
- /* object starting at the ith word (header */
- /* INCLUDED) in the heap block. */
- /* For free blocks, hbh_marks[0] = 1, indicates */
- /* block is uninitialized. */
- };
-
- /* heap block body */
-
- # define BODY_SZ ((HBLKSIZE-sizeof(struct hblkhdr))/sizeof(word))
-
- struct hblk {
- struct hblkhdr hb_hdr;
- word hb_body[BODY_SZ];
- };
-
- # define hb_sz hb_hdr.hbh_sz
- # define hb_index hb_hdr.hbh_index
- # define hb_marks hb_hdr.hbh_marks
- # define hb_next hb_hdr.hbh_next
- # define hb_uninit hb_hdr.hbh_marks[0]
- # define hb_mask hb_hdr.hbh_mask
-
- /* lists of all heap blocks and free lists */
- /* Primary declaration is in alloc.c */
- /* These are grouped together in s struct */
- /* so that they can be easily skipped by the */
- /* mark routine. */
- /* misc.c knows about their relative order. */
-
- struct __gc_arrays {
- struct obj * _aobjfreelist[MAXAOBJSZ+1]; /* free list for atomic objs*/
- struct obj * _objfreelist[MAXOBJSZ+1]; /* free list for objects */
- struct hblk * _hblklist[MAXHBLKS];
- };
-
- extern struct __gc_arrays _gc_arrays;
-
- # define objfreelist _gc_arrays._objfreelist
- # define aobjfreelist _gc_arrays._aobjfreelist
- # define hblklist _gc_arrays._hblklist
-
- # define begin_gc_arrays ((char *)(&_gc_arrays))
- # define end_gc_arrays (((char *)(&_gc_arrays)) + (sizeof _gc_arrays))
-
- struct hblk ** last_hblk; /* Pointer to one past the real end of hblklist */
-
- struct hblk * hblkfreelist;
-
- extern long heapsize; /* Heap size in bytes */
-
- # define HINCR 16 /* Initial heap increment, in blocks */
- long hincr; /* current heap increment, in blocks */
-
- /* Operations */
- # define update_hincr hincr = (hincr * HINCR_MULT)/HINCR_DIV
- # define HB_SIZE(p) abs((p) -> hb_sz)
- # define abs(x) ((x) < 0? (-(x)) : (x))
-
- /* procedures */
-
- extern void
- freehblk();
-
- extern struct hblk *
- allochblk();
-
- /****************************/
- /* */
- /* Objects */
- /* */
- /****************************/
-
- /* object structure */
-
- struct obj {
- union fredhead {
- struct obj *oun_link; /* --> next object in freelist */
- # define obj_link obj_un.oun_link
- word oun_component[1]; /* treats obj as list of words */
- # define obj_component obj_un.oun_component
- } obj_un;
- };
-
- /* Test whether something points to a legitimate heap object */
-
-
- extern char end;
-
- char * heaplim; /* 1 + last address in heap */
-
- char * startup_sfp; /* Frame pointer for Russell startup routine */
-
- /* Check whether the given HBLKSIZE aligned hblk pointer refers to a */
- /* legitimate chunk. */
- /* Assumes that *p is addressable */
- #define is_hblk(p) ( (p) -> hb_index >= hblklist \
- && (p) -> hb_index < last_hblk \
- && *((p)->hb_index) == (p))
-
- /* Check whether q points to an object inside hblk p for objects of size s */
- /* with mask m corresponding to s. */
- /* Assumes q-p and s << 2 each fit into a short. */
- #define is_proper_obj(q,p,s,m) \
- (((long)(m)) >= 0 ? \
- (((((long)(q)) - (sizeof (struct hblkhdr))) & (m)) == 0) \
- : (((short)(((long) (q)) - ((long)(p)) - (sizeof (struct hblkhdr)))) \
- % (((short)(s)) << 2) == 0))
-
- /* The following is a quick test whether something is an object pointer */
- /* It may err in the direction of identifying bogus pointers */
- /* Assumes heap + text + data + bss < 64 Meg. */
- #ifdef M68K
- # define POINTER_MASK 0xfc000003 /* pointer & POINTER_MASK should be 0 */
- #else
- # ifdef VAX
- # define POINTER_MASK 0xfc000003
- # else
- # ifdef SPARC
- # define POINTER_MASK 0xfc000003
- # else
- # ifdef I386
- # define POINTER_MASK 0xfc000003
- # else
- --> dont know <--
- # endif
- # endif
- # endif
- #endif
-
- #ifdef UNALIGNED
- # define quicktest(p) (((long)(p)) > ((long)(&end)) \
- && !(((unsigned long)(p)) & POINTER_MASK) \
- && (((long)(p)) & HBLKMASK))
- /* The last test throes out pointers to the beginning of heap */
- /* blocks. Small integers shifted by 16 bits tend to look */
- /* like these. */
- #else
- # define quicktest(p) (((long)(p)) > ((long)(&end)) \
- && !(((unsigned long)(p)) & POINTER_MASK))
- #endif
-
-
- /* Marks are in a reserved area in */
- /* each heap block. Each word has one mark bits associated */
- /* with it. Only those corresponding to the beginning of an */
- /* object are used. */
-
-
- /* Operations */
-
- /*
- * Retrieve, set, clear the mark bit corresponding
- * to the nth word in a given heap block.
- * Note that retrieval will work, so long as *hblk is addressable.
- * In particular, the check whether hblk is a legitimate heap block
- * can be postponed until after the mark bit is examined.
- *
- * (Recall that bit n corresponds to object beginning at word n)
- */
-
- # define mark_bit(hblk,n) (((hblk)->hb_marks[divWORDSZ(n)] \
- >> (modWORDSZ(n))) & 1)
-
- /* The following assume the mark bit in question is either initially */
- /* cleared or it already has its final value */
- # define set_mark_bit(hblk,n) (hblk)->hb_marks[divWORDSZ(n)] \
- |= 1 << modWORDSZ(n)
-
- # define clear_mark_bit(hblk,n) (hblk)->hb_marks[divWORDSZ(n)] \
- &= ~(1 << modWORDSZ(n))
-
- /* procedures */
-
- /* Small object allocation routines */
- extern struct obj * allocobj();
- extern struct obj * allocaobj();
-
- /* general purpose allocation routines */
- extern struct obj * ralloc();
-
- extern struct obj * ralloc_comp();
-
-